#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<mysql/mysql.h>

using namespace std;

int show(MYSQL_RES *res)
{
    MYSQL_ROW row;
    int cnt = 0;
    while(row = mysql_fetch_row(res))
    {
        for(int i = 0;i<mysql_num_fields(res);i++)
            printf("%s ",row[i]);
        printf("...\n");
        cnt++;
        row = mysql_fetch_row(res);
    }
    return cnt;
}

int handData(char *buf,int confd)
{
    char type[3] = {0};
    cout << buf<<endl;
    strncpy(type,buf+1,2);
    if(strcmp(type,"01") == 0)
    {
        char uName[32] = {0};
        char pWord[32] = {0};
        sscanf(buf+4,"%[^|]|%s",uName,pWord);
        cout <<"uname = "<< uName << endl;
        cout << "pWord = "<<pWord<<endl;
        char sqlStr[1024] = {0};
        sprintf(sqlStr,"select * from person where uName = '%s';",uName); 
        MYSQL mysql;
        MYSQL_RES *result = NULL;
        MYSQL_ROW row;
        if(mysql_init(&mysql) == NULL)
        {
            cout << "init failure" << endl;
            return -1;
        }
        //mysql_real_connect(&mysql,"127.0.0.1","root","yxqyxq1A","qq",0,NULL,0);
        if(mysql_real_connect(&mysql,"127.0.0.1","root","zhouyu100","account",0,NULL,0) == NULL)
        {
            cout << "connection failure" << endl;
            return -1;
        }
        if(mysql_query(&mysql,sqlStr)!=0)
        {
            cout << "query error" << endl;
            return -1;
        }
        result = mysql_store_result(&mysql);
        if(result == NULL)
        {
            cout << "result error" <<endl;
            return -1;
        }
        int r = show(result);
        row = mysql_fetch_row(result);
        if(r > 0)
        {
            write(confd, "#01|1|userExist", sizeof("#01|1|userExist"));
            printf("number of rows %d\n", r);
        }
        else
        {
            write(confd, "#01|0|regSuccess", sizeof("#01|0|regSuccess"));
            sprintf(sqlStr, "insert into UserTb values('%s','%s',0);", uName, pWord);
            mysql_query(&mysql, sqlStr);
            sprintf(sqlStr, "insert into person values('%s');", uName);
            mysql_query(&mysql, sqlStr);
            sprintf(sqlStr, "select * from UserTb where userName = '%s';", uName);
            mysql_query(&mysql, sqlStr);
            result = mysql_store_result(&mysql);
            printf("number of rows %d\n", show(result));
        }
        mysql_free_result(result);
        mysql_close(&mysql);
    }
    return 0;
}

int main()
{
    struct sockaddr_in sevaddr;
    memset(&sevaddr,0,sizeof(sevaddr));
    sevaddr.sin_family = AF_INET;
    sevaddr.sin_port = htons(8899);
    sevaddr.sin_addr.s_addr = inet_addr("192.168.135.134");
    int clifd[1024] = {0};
    int confd = 0;
    int maxfd = 0;
    int curi = 0;
    int i = 0;
    fd_set allset;
    fd_set rset;
    FD_ZERO(&allset);
    int lisfd = socket(AF_INET,SOCK_STREAM,0);
    if(bind(lisfd,(struct sockaddr *)&sevaddr,sizeof(sevaddr)) != 0)
    {
        //printf("bind error\n");
        cout << "bind error" << endl;
        return -1;
    }
    listen(lisfd,10);
    FD_SET(lisfd,&allset);
    if(lisfd > maxfd)
    {
        maxfd = lisfd;
    }
    while(1)
    {
        rset = allset;
        int nready = select(maxfd+1,&rset,NULL,NULL,NULL);
        if(nready <= 0)
        {
            cout << "select error" << endl;
            return -1;
        }
        if(FD_ISSET(lisfd,&rset))
        {
            confd = accept(lisfd,NULL,NULL);
            if(confd == -1)
            {
                // printf("accept error\n");
                cout << "accept error" << endl;
                return -1;
            }  
            FD_SET(confd,&allset);
            if(confd > maxfd)
                maxfd = confd;
            //clifd[curi++] = maxfd;
            for(i=0;i<curi;i++)
            {
                if(clifd[i] == -1)
                {
                    clifd[i] = confd;
                    break;
                }
            }
            if(i == curi)
            {
                if(curi == 1024)
                {
                    cout << "max fd" << endl;
                }
                else
                    clifd[curi++] = confd;
            }
        }
        //cout << curi << endl;
        for(int i=0;i<curi;i++)
        {
            confd = clifd[i];
            if(FD_ISSET(confd,&rset))
            {
                char buf[1024] = {0};
                if(read(confd,buf,sizeof(buf)) == 0)
                {
                    FD_CLR(confd,&allset);
                    clifd[i] = -1;
                    continue;
                }
                //printf("buf = %s\n",buf);
                //write(confd,"ok",2);
                handData(buf,confd);
            }
        }
        //cout << curi << endl;
        // char buf[1024] = {0};
        // while(1)
        // {
        //     read(confd,buf,sizeof(buf));
        //     printf("buf = %s\n",buf);
        //     write(confd,"ok",2);
        // }
    }
}
